/******************************************************************************
* This file is part of is32p218 platform,
* Copyright (c) 2009 HangZhou InfoStrong CO.,LTD. All rights reserved.
* This software may only be used under the terms of a valid, current,
* end user license from InfoStrong.
* Nothing else gives you the right to use this software.   
*
* Name:   drv_tmr.c
* Desc:   Timer module driver C file
* Author: Jerry
* Date:   2009-9-16
* Note:   
* History:
*
******************************************************************************/
#include "option.h"
#include "xn5106x.h"
#include "drv_sys.h"
#include "drv_tmr.h"

/*
* Function Name:
*   drv_tmr_set
* Description:
*   Timer value setting
* Parameters:
*   S32 tmr_num: Timer number(0~5)
*   U32 interval: n us(unit is us) (max: (256*65536)/TMR_UTCLK_REQ )
* Returns:
*   BOOL
* Author				Date 
*  Jerry				2009-9-16   
* Note:
*    
*/
BOOL drv_tmr_set( S32 tmr_num, U32 interval )
{
	VU8 *p_tmr_con;
	VU8 *p_tmr_pre;
	VU16 *p_tmr_data;
	U32 addr_offset;
	U32 total_val;
	U32 pre_val;
	U32 data_val;
	
	if (tmr_num>TMR_NO_MAX||0==interval \
		||interval>(256*65536)/(TMR_UTCLK_REQ/1000000))
	{
		IS_ASSERT(0);
		return FALSE;
	}
	addr_offset = (TMR_ADDR_GAP*tmr_num); 
	p_tmr_con = &rT0CON;
	p_tmr_con += addr_offset;
	*p_tmr_con &= (~BIT7);	/* Disable timer */

	p_tmr_pre = &rT0PRE;
	p_tmr_pre += addr_offset;

	p_tmr_data = &rT0DATA;
	p_tmr_data = (VU16*)((VU8*)p_tmr_data+addr_offset);

	/* Calculate Interval Register Value */
	total_val = ((TMR_UTCLK_REQ/1000000)*(interval));
	pre_val = (total_val>>16);
	if (total_val&0xFFFF)
	{
		pre_val++;
	}
	if (pre_val>0x100)
	{	/* Interval is so large */
		IS_ASSERT(0);
		return FALSE;
	}
	for (;pre_val<=0x100; pre_val++)
	{
		if (0 == ((total_val%pre_val)))
		{
			break;
		}
	}

	data_val = total_val/pre_val;

	*p_tmr_pre = pre_val-1;
	*p_tmr_data = data_val-1;
	return TRUE;
}

/*
* Function Name:
*   drv_tmr_check
* Description:
*   Timer value check
* Parameters:
*   S32 tmr_num: Timer number(0~5)
*   U32 interval: n us(unit is us) (max: (256*65536)/TMR_UTCLK_REQ )
* Returns:
*   BOOL
* Author				Date 
*  feye 				2010-6-2   
* Note:
*    
*/
BOOL drv_tmr_check( S32 tmr_num, U32 interval )
{
	VU8 *p_tmr_con;
	VU8 *p_tmr_pre;
	VU16 *p_tmr_data;
	U32 addr_offset;
	U32 total_val;
	U32 pre_val;
	U32 data_val;
	
	if (tmr_num>TMR_NO_MAX||0==interval)
	{
		IS_ASSERT(0);
		return FALSE;
	}
	addr_offset = (TMR_ADDR_GAP*tmr_num); 
	p_tmr_con = &rT0CON;
	p_tmr_con += addr_offset;
//	*p_tmr_con &= (~BIT7);	/* Disable timer */

	p_tmr_pre = &rT0PRE;
	p_tmr_pre += addr_offset;

	p_tmr_data = &rT0DATA;
	p_tmr_data = (VU16*)((VU8*)p_tmr_data+addr_offset);

	/* Calculate Interval Register Value */
	total_val = ((TMR_UTCLK_REQ/1000000)*(interval));
	pre_val = (total_val>>16);
	if (total_val&0xFFFF)
	{
		pre_val++;
	}
	if (pre_val>0x100)
	{	/* Interval is so large */
		IS_ASSERT(0);
		return FALSE;
	}
	for (;pre_val<=0x100; pre_val++)
	{
		if (0 == ((total_val%pre_val)))
		{
			break;
		}
	}

	data_val = total_val/pre_val;

	if(((pre_val-1)!=*p_tmr_pre)||((data_val-1)!=*p_tmr_data))
	{
		return FALSE;
	}
	
	return TRUE;
}



/*
* Function Name:
*   drv_tmr_ena
* Description:
*   Enable/Disable Timer
* Parameters:
*   S32 tmr_num: Timer number(0~5)
*   BOOL flg: TRUE--Enable; FALSE--Disable
* Returns:
* Author				Date 
*  Jerry				2009-9-16   
* Note:
*    
*/
void drv_tmr_ena( S32 tmr_num, BOOL flg )
{
	VU8 *p_tmr_con;
	if (tmr_num>TMR_NO_MAX)
	{
		IS_ASSERT(0);
		return;
	}
	p_tmr_con = &rT0CON;
	p_tmr_con += (TMR_ADDR_GAP*tmr_num);

	rINTPEND = (~(BIT_T0OVF<<(tmr_num<<1)));	// Clear timer Flags
	rINTPEND = (~(BIT_T0MC<<(tmr_num<<1)));		// Clear timer Flags
	if (flg)
	{
		*p_tmr_con |= (BIT6|BIT7);	/* Clear timer count and Enable */
	}
	else
	{
		*p_tmr_con &= (~BIT7);
	}
}

/*
* Function Name:
*   drv_tmr_ena_check
* Description:
*   Enable/Disable Timer check
* Parameters:
*   S32 tmr_num: Timer number(0~5)
*   BOOL flg: TRUE--Enable; FALSE--Disable
* Returns:
* Author				Date 
*  feye				    2010-6-2   
* Note:
*    
*/
BOOL drv_tmr_ena_check( S32 tmr_num, BOOL flg )
{
	VU8 *p_tmr_con;
	if (tmr_num>TMR_NO_MAX)
	{
		IS_ASSERT(0);
		return FALSE;
	}
	p_tmr_con = &rT0CON;
	p_tmr_con += (TMR_ADDR_GAP*tmr_num);

	if (flg)
	{
		return (*p_tmr_con&BIT7)?TRUE:FALSE;	
	}
	else
	{
		return (*p_tmr_con&BIT7)?FALSE:TRUE;
	}
}


/*
* Function Name:
*   drv_tmr_tmout
* Description:
*   Timer timeout check
* Parameters:
*   S32 tmr_num: Timer number(0~5)
* Returns:
*  	BOOL:
*  		  TRUE: Overflow
*  		  FALSE: Not Overflow
* Author				Date 
*  Jerry				2010-1-21   
* Note:
*    
*/
BOOL drv_tmr_tmout( S32 tmr_num )
{
	U32 msk_bit;
	msk_bit = BIT_T0MC<<(tmr_num<<1);
	return ((rINTPEND&msk_bit)==msk_bit)?TRUE:FALSE;
}

/*
* Function Name:
*   drv_tmr_init
* Description:
*   Timer Module Init
* Parameters: 
*   None 
* Returns: 
*   None 
* Author				Date 
*  Jerry				2009-9-16   
* Note:
*    
*/
void drv_tmr_init( void )
{
	S32 i;
	for (i=0; i<=TMR_NO_MAX; i++)
	{
		drv_tmr_ena( i, FALSE );
	}
}

/*
* Function Name:
*   drv_tmr_status_check
* Description:
*   Timer Module status check
* Parameters: 
*   None 
* Returns: 
*   None 
* Author				Date 
*  feye				    2010-6-2   
* Note:
*    
*/
BOOL drv_tmr_status_check( void )
{
	if(!drv_tmr_ena_check( TMR0_OS, TRUE))
	{
		return FALSE;
	}

	return TRUE;
}

/*
* Function Name:
*   drv_tmr_status_set
* Description:
*   Timer Module status set
* Parameters: 
*   None 
* Returns: 
*   None 
* Author				Date 
*  feye				    2010-6-2   
* Note:
*    
*/
void drv_tmr_status_set( void )
{
	drv_tmr_ena( TMR0_OS, TRUE);
}


